package com.hnichr.ump.plan.service.impl;

import com.hnichr.ump.common.plan.Auth;
import com.hnichr.ump.common.plan.entity.PlanScheduleContentDept;
import com.hnichr.ump.common.plan.entity.PlanScheduleContents;
import com.hnichr.ump.common.plan.entity.PlanSchedules;
import com.hnichr.ump.common.plan.entity.PlanSchedulesDept;
import com.hnichr.ump.common.plan.service.PlanAuthService;
import com.hnichr.ump.common.plan.service.PlanSchedulesService;
import com.hnichr.ump.common.plan.vo.PlanAuthVo;
import com.hnichr.ump.common.plan.vo.PlanSchedulesVo;
import com.hnichr.ump.common.util.DeptUtils;
import com.mxpioframework.jpa.JpaUtil;
import com.mxpioframework.jpa.query.Criteria;
import com.mxpioframework.security.entity.Dept;
import com.mxpioframework.security.util.SecurityUtils;
import com.mxpioframework.system.service.impl.BaseServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.data.domain.Pageable;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.stream.Collectors;


@Service
@Slf4j
public class PlanSchedulesServiceImpl extends BaseServiceImpl<PlanSchedules> implements PlanSchedulesService {

    @Autowired
    private PlanAuthService planAuthService;

    @Override
    @Transactional(readOnly = true)
    public List<PlanSchedules> list(Criteria c){
        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }
        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(planAuthVo.getView().equals(Auth.NONE)){
            return Collections.emptyList();
        }
        List<PlanSchedules> schedules;

        if(planAuthVo.getView().equals(Auth.ALL)){
            schedules = list(PlanSchedules.class,c);
        }
        else if(planAuthVo.getView().equals(Auth.DEPT)){
            schedules = JpaUtil.linq(PlanSchedules.class)
                    .exists(PlanSchedulesDept.class)
                    .equalProperty("scheduleId","id")
                    .like("deptCode",deptCode+"%")
                    .end()
                    .where(c).list();
        }
        else{
            return Collections.emptyList();
        }


        getMgrDept(schedules);
        return schedules;
    }

    @Override
    @Transactional(readOnly = true)
    public Page<PlanSchedules> listPage(Pageable page, Criteria c){
        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }
        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(planAuthVo.getView().equals(Auth.NONE)){
            return Page.empty();
        }
        Page<PlanSchedules> schedules;
        if(planAuthVo.getView().equals(Auth.ALL)){
            schedules = listPage(PlanSchedules.class,page,c);
        }
        else if(planAuthVo.getView().equals(Auth.DEPT)){
            schedules = JpaUtil.linq(PlanSchedules.class)
                    .exists(PlanSchedulesDept.class)
                    .equalProperty("scheduleId","id")
                    .like("deptCode",deptCode+"%")
                    .end()
                    .where(c).paging(page);
        }
        else{
            return Page.empty();
        }
        getMgrDept(schedules.getContent());
        return schedules;
    }

    @Override
    @Transactional(readOnly = true)
    public PlanSchedules getById(String id){
        PlanSchedules schedule = JpaUtil.getOne(PlanSchedules.class, id);
        List<PlanSchedulesDept> planSchedulesDepts = JpaUtil.linq(PlanSchedulesDept.class).equal("scheduleId",schedule.getId()).list();
        schedule.setMgrDept(planSchedulesDepts);
        return schedule;
    }

    @Override
    @Transactional
    public PlanSchedules save(PlanSchedulesVo scheduleVo){
        PlanSchedules planSchedules = new PlanSchedules();
        planSchedules.setMgrDept(new ArrayList<>());
        BeanUtils.copyProperties(scheduleVo,planSchedules);
        JpaUtil.save(planSchedules);
        saveDept(scheduleVo,planSchedules);
        return planSchedules;
    }

    @Override
    @Transactional
    public PlanSchedules edit(PlanSchedulesVo scheduleVo){
        PlanSchedules planSchedules = new PlanSchedules();
        planSchedules.setMgrDept(new ArrayList<>());
        BeanUtils.copyProperties(scheduleVo,planSchedules);
        JpaUtil.update(planSchedules);

        List<PlanSchedulesDept> planSchedulesDepts = JpaUtil.linq(PlanSchedulesDept.class).equal("scheduleId",scheduleVo.getId()).list();
        if(CollectionUtils.isNotEmpty(planSchedulesDepts)){
            for(PlanSchedulesDept p:planSchedulesDepts){
                JpaUtil.delete(p);
            }
        }
        saveDept(scheduleVo,planSchedules);

        return planSchedules;
    }

    @Override
    @Transactional
    public void remove(String ids){
        String [] ida = StringUtils.split(ids,",");
        for(String id:ida){
            List<PlanSchedulesDept> planSchedulesDepts = JpaUtil.linq(PlanSchedulesDept.class).equal("scheduleId",id).list();
            if(CollectionUtils.isNotEmpty(planSchedulesDepts)){
                for(PlanSchedulesDept p:planSchedulesDepts){
                    JpaUtil.delete(p);
                }
            }
            PlanSchedules planSchedules = JpaUtil.getOne(PlanSchedules.class,id);
            JpaUtil.delete(planSchedules);
        }
    }

    @Override
    @Transactional(readOnly = true)
    public void getContents(List<PlanSchedules> ls){
        if(CollectionUtils.isEmpty(ls)){
            return;
        }
        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }
        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(!planAuthVo.getView().equals(Auth.ALL)&&!planAuthVo.getView().equals(Auth.DEPT)){
            return;
        }
        for(PlanSchedules planSchedules:ls){
            List<PlanScheduleContents> contents;
            if(planAuthVo.getView().equals(Auth.ALL)){
                contents = JpaUtil.linq(PlanScheduleContents.class).equal("schedulesId",planSchedules.getId()).list();
            }
            else{
                contents = JpaUtil.linq(PlanScheduleContents.class).equal("schedulesId",planSchedules.getId())
                        .exists(PlanScheduleContentDept.class)
                        .equalProperty("id","contentId")
                        .end()
                        .list();
            }
            contents = contents.stream().sorted(Comparator.comparing(PlanScheduleContents::getCreateTime,Comparator.reverseOrder())).collect(Collectors.toList());
            planSchedules.setContentList(contents);
            for(PlanScheduleContents content:contents){
                content.setDeptList(JpaUtil.linq(PlanScheduleContentDept.class).equal("contentId",content.getId()).list());
            }
        }
    }

    private void saveDept(PlanSchedulesVo scheduleVo,PlanSchedules planSchedules){
        PlanAuthVo planAuthVo = planAuthService.getUserAuth();
        if(planAuthVo.getEdit().equals(Auth.NONE)){
            log.error("{}部门权限为none,不允许保存部门信息",SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门权限");
        }

        String deptCode = DeptUtils.getDeptCode();
        if(StringUtils.isBlank(deptCode)){
            log.error(">>>>>>>>>>>>{}无部门", SecurityUtils.getLoginUsername());
            throw new RuntimeException("无部门");
        }

        List<String> deptIds = scheduleVo.getDeptIds();
        List<PlanSchedulesDept> deptLs = new ArrayList<>();
        boolean isDeptIncluded = false;
        if(CollectionUtils.isNotEmpty(deptIds)){
            for(String deptId:deptIds){
                Dept dept = JpaUtil.getOne(Dept.class,deptId);
                if(dept!=null){
                    PlanSchedulesDept scheDept = new PlanSchedulesDept();
                    scheDept.setScheduleId(planSchedules.getId());
                    scheDept.setDeptId(dept.getId());
                    scheDept.setDeptCode(dept.getDeptCode());
                    scheDept.setDeptName(dept.getDeptName());
                    deptLs.add(scheDept);
                    if(StringUtils.startsWith(dept.getDeptCode(),deptCode)){
                        isDeptIncluded = true;
                    }
                }
            }
        }
        if(planAuthVo.getEdit().equals(Auth.DEPT)&&!isDeptIncluded){
            throw new RuntimeException("主责部门未包含本人所属部门或下级部门");
        }
        for(PlanSchedulesDept scheDept:deptLs){
            planSchedules.getMgrDept().add(scheDept);
            JpaUtil.save(scheDept);
        }

    }

    private void getMgrDept(List<PlanSchedules> schedules){
        if(CollectionUtils.isEmpty(schedules)){
            return;
        }
        for(PlanSchedules schedule:schedules){
            List<PlanSchedulesDept> planSchedulesDepts = JpaUtil.linq(PlanSchedulesDept.class).equal("scheduleId",schedule.getId()).list();
            schedule.setMgrDept(planSchedulesDepts);
        }
    }

}
